from docx import Document
from docx.shared import Pt
from docx.enum.text import WD_LINE_SPACING
from pathlib import Path
import re
import os

"""
    使用流程
1.将代码复制到项目目录下
2.替换需要扫描的文件后缀名称
3.本代码针对于java项目编写，如其他项目请修改注释删除逻辑
"""

def findFileBySuf(path, suffix):
    fileList = []
    try:
        # 获取path路径下所有的文件和目录名称列表
        dirList = os.listdir(path)
    except FileNotFoundError:
        print(f"指定的路径 {path} 不存在")
        return fileList

    for file in dirList:
        nowPath = Path(path) / file  # 使用Path对象进行路径拼接更安全
        if nowPath.is_dir():
            # 递归查找子目录中的文件
            subFileList = findFileBySuf(nowPath, suffix)
            fileList.extend(subFileList)
        elif file.endswith(suffix):
            fileList.append(str(nowPath))
    return fileList

# 针对一个文件，去掉注释，去掉空行
# 返回删掉file文件的的空行和注释的内容
def filterContent(content):
    with open(content, 'r', encoding='utf-8') as file:
        fileContent = file.read()
        # 按\n分割成列表
        fileList = fileContent.splitlines()
        for line in fileList[:]:
            if line == '':
                fileList.remove(line)
            if re.match(r'^\s+$', line):
                # 删除掉空白字符行,如删除以空格开头且没有字符的行
                fileList.remove(line)
            if line.lstrip().startswith("/"):
                fileList.remove(line)
            if line.lstrip().startswith("*"):
                fileList.remove(line)
    # 将多个元素连接成一个字符串给res
    res = '\n'.join(fileList) + '\n'
    # 返回去格式的代码和代码行数
    return res, len(fileList)


# 将处理后的代码写入并保存到指定doc文件下
def saveDocFile(flist, savepath):
    # SINGLE         =>  单倍行距（默认）
    # ONE_POINT_FIVE =>  1.5倍行距
    # DOUBLE2        =>  倍行距
    # AT_LEAST       =>  最小值
    # EXACTLY        =>  固定值
    # MULTIPLE       =>  多倍行距
    doc = Document()
    p = doc.add_paragraph('')  # 增加一页
    doc.styles['Normal'].font.name = 'Times New Roman'  # 正文是normal， 设置正文的字体格式
    doc.styles['Normal'].font.size = Pt(8)  # 设置字体的大小为 5 号字体
    p.line_spacing_rule = WD_LINE_SPACING.EXACTLY  # 固定值
    paragraph_format = doc.styles['Normal'].paragraph_format
    paragraph_format.line_spacing = Pt(12.9)  # 固定值12,9磅, 保证每页有50行代码

    lines = 0
    for i, f in enumerate(flist):
        tempStr = 'starting deal with %d/%d' % (i + 1, len(flist))
        print(tempStr + "    " + f)
        codef, codelies = filterContent(f)
        lines += codelies
        p.add_run(codef)
        # 可选功能：如果开启以下模块，当代码到达3000行，不再写入代码
        # if lines > 3000:
        # doc.save(savepath)
        # return
        # else:
        # p.add_run(codef)
    # 所有代码整合完毕后，保存doc文件
    doc.save(savepath)


# MAIN函数
if __name__ == '__main__':
    path = os.getcwd()
    savePath = path + os.sep + "code.doc"  # 设置保存doc文件的路径
    fileList = findFileBySuf(path, '.java')  # 从中筛选出.f90文件并覆盖到fileList中
    saveDocFile(fileList, savePath)
    print('all done')
